#include "PrecompiledHeaders.h"
#include "ScoreToppleControl.h"
#include "FromString.h"

ScoreToppleControl::ScoreToppleControl()
{

}

ScoreToppleControl *ScoreToppleControl::clone()
{
    ScoreToppleControl *stc = new ScoreToppleControl();
    std::map<OgreNewt::Body *, ScoreToppleObjectData>::iterator it;
    for (it = score_topple_objects.begin(); it != score_topple_objects.end(); it++) {
        ScoreToppleObjectData d = it->second;
        stc->score_topple_objects[it->first] = d;
    }
    return stc;
}

void ScoreToppleControl::reset()
{
    std::map<OgreNewt::Body *, ScoreToppleObjectData>::iterator it;
    for (it = score_topple_objects.begin(); it != score_topple_objects.end(); it++) {
        it->second.done = false;
    }
}

void ScoreToppleControl::addScoreToppleObject(OgreNewt::Body *body, std::map<Ogre::String, Ogre::String> &params)
{
    body->setUserData(this);
    
    ScoreToppleObjectData data;
    data.done = false;
    
    Ogre::Vector3 pos;
    body->getPositionOrientation(pos, data.initial_orientation);
    
    std::map<Ogre::String, Ogre::String>::iterator it;
    it = params.find("score_amount");
    if (it != params.end())
        from_string<int>( data.score_amount, it->second.c_str(), std::dec);
    else
        data.score_amount = STO_DEFAULT_SCORE;
    
    score_topple_objects[body] = data;
}

void ScoreToppleControl::collision(OgreNewt::Body *object)
{
    std::map<OgreNewt::Body *, ScoreToppleObjectData>::iterator it;
    it = score_topple_objects.find(object);
    if (it != score_topple_objects.end())
    {
        if (! it->second.done) {
            Ogre::Quaternion orientation;
            Ogre::Vector3 pos;
            object->getPositionOrientation(pos, orientation);
            
            if (isToppled(it->second.initial_orientation, orientation))
            {
                it->second.done = true;
                player->getSession()->addScore(it->second.score_amount);
                
                if (player->isMainPlayer())
                    play_state->updateScoreOverlay();
            }
        }
    }
}

bool ScoreToppleControl::isToppled(Ogre::Quaternion &initial, Ogre::Quaternion &current)
{
    Ogre::Real ini_pitch = initial.getPitch(false).valueRadians();
    Ogre::Real ini_roll = initial.getRoll(false).valueRadians();
    Ogre::Real cur_pitch = current.getPitch(false).valueRadians();
    Ogre::Real cur_roll = current.getRoll(false).valueRadians();
    //printf("init p=%f,r=%f  cur p=%f,r=%f\n", ini_pitch, ini_roll, cur_pitch, cur_roll);
    return (fabs(ini_pitch - cur_pitch) > 1 ||
            fabs(ini_roll - cur_roll) > 1);
}
